/*
 * tasks.hpp
 *
 *  Created on: Mar 4, 2009
 *      Author: shl
 */

#ifndef TASKS_HPP_
#define TASKS_HPP_

#include "log.hpp"

#include <boost/exception.hpp>
#include <boost/thread/barrier.hpp>

namespace fixstoker {

class abstract_task {
public:
	enum task_status {NOT_STARTED, STARTED, FINISHED, ERROR};

	abstract_task(const char* name, boost::barrier* b): name_(name), barrier_(b), status_(NOT_STARTED) {};

	void operator()() {
		LOG_DEBUG("task: " << name_ << ", startup synchronization, waiting...");
		barrier_->wait();
		LOG_DEBUG("task: " << name_ << ", startup synchronization, passed");

		try {
			this->status_ = STARTED;
			this->do_operator_();
			this->status_ = FINISHED;
		} catch(const boost::exception& e) {
			this->status_ = ERROR;
			LOG_ERROR("Exception, task: " << name_ << boost::diagnostic_information(e));
		} catch(...) {
			this->status_ = ERROR;
			LOG_ERROR("Unexpected Exception, task: " << name_);
		}

		LOG_DEBUG("task: " << name_ << ", shutdown synchronization, waiting...");
		barrier_->wait();
		LOG_DEBUG("task: " << name_ << ", shutdown synchronization, passed");
	};

	task_status status() const { return this->status_; }

	const char* name() const { return this->name_; }

protected:
	virtual void do_operator_() const  = 0;

	const char* name_;
	boost::barrier* barrier_;
	task_status status_;
};


class tx_task: public abstract_task {
public:
	tx_task(boost::barrier* b): abstract_task("tx_task", b) {};

protected:
	virtual void do_operator_() const;
};


class rx_task: public abstract_task {
public:
	rx_task(boost::barrier* b): abstract_task("rx_task", b) {};

protected:
	virtual void do_operator_() const;
};


bool run_all_tasks();

}

#endif /* TASKS_HPP_ */
